package com.xquant.common.log.aspect;

import com.alibaba.fastjson2.JSON;
import com.xquant.common.core.utils.ServletUtils;
import com.xquant.common.core.utils.StringUtils;
import com.xquant.common.core.utils.ip.IpUtils;
import com.xquant.common.log.annotation.ImportLog;
import com.xquant.common.log.annotation.Log;
import com.xquant.common.log.enums.BusinessStatus;
import com.xquant.common.log.enums.ImportErrCode;
import com.xquant.common.log.service.AsyncLogService;
import com.xquant.common.security.utils.SecurityUtils;
import com.xquant.system.api.domain.SysOperLog;
import com.xquant.system.api.domain.TsysInterfaceLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 导入日志切面类
 *
 * @author cloud
 */
@Aspect
@Component
public class ImportLogAspect {
    private static final Logger log = LoggerFactory.getLogger(ImportLogAspect.class);

    @Autowired
    private AsyncLogService asyncLogService;

    /**
     * 在有@ImportLog的方法执行完后执行
     *
     * @param joinPoint 切点
     */
    @AfterReturning(pointcut = "@annotation(importLog)", returning = "res")
    public void doAfterReturning(JoinPoint joinPoint, ImportLog importLog, Object res) {
        handleLog(joinPoint, importLog, null, res);
    }


    protected void handleLog(final JoinPoint joinPoint, ImportLog importLog, final Exception e, Object res) {
        try {
            TsysInterfaceLog interfaceLog = new TsysInterfaceLog();
            interfaceLog.setUnique(importLog.unique() ? 1 : 0);

            Map resMap = (Map<String, Object>) res;
            if ((boolean) resMap.get("OK")) {
                interfaceLog.setErrCode(ImportErrCode.SUCCESS.ordinal());
            } else {
                interfaceLog.setErrCode(ImportErrCode.FAIL.ordinal());
            }
            interfaceLog.setErrMsg(String.valueOf(resMap.get("msg") == null ? "" : resMap.get("msg")));
            Object[] args = joinPoint.getArgs();
            //设置批次号
            interfaceLog.setBatchNo(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
            //设置操作时间
            interfaceLog.setOpTime(new Date());
            //设置操作人
            if (StringUtils.isNotEmpty(importLog.userId())) {
                // 自动导入给系统管理员
                interfaceLog.setUserId("1");
            } else {
                // 手动导入给操作人
                interfaceLog.setUserId(SecurityUtils.getUserId().toString());
            }
            //接口数据
            interfaceLog.setOriginInfo(JSON.toJSONString(args[0]));
            // 处理设置注解上的参数
            getMethodDescription(joinPoint, importLog, interfaceLog, res);

            // 保存数据库
            asyncLogService.saveImportLog(interfaceLog);
        } catch (Exception exp) {
            // 记录本地异常日志
            log.error("==前置通知异常==");
            log.error("异常信息:{}", exp.getMessage());
            exp.printStackTrace();
        }
    }

    /**
     * 获取注解中对方法的描述信息
     *
     * @param importLog 日志
     * @param
     * @throws Exception
     */
    public void getMethodDescription(JoinPoint joinPoint, ImportLog importLog, TsysInterfaceLog interfaceLog, Object res) throws Exception {
        //设置业务编码，需要根据反射和注解一起获取
        Object[] args = joinPoint.getArgs();
        Method method = args[0].getClass().getMethod(importLog.businNoMethod());
        interfaceLog.setBusinNo((String) method.invoke(args[0]));
        //设置actionType
        interfaceLog.setActionType(importLog.actionType().ordinal());
        //设置optionType
        interfaceLog.setOpType(importLog.optionType().ordinal());

    }


}
